home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
comm
/
superv22.zip
/
EXEC.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1986-12-02
|
5KB
|
164 lines
Type
Exec_Str66=String[66]; {Used for paths, filenames, etc}
Exec_Str255=String[255]; {Main command string type}
Var
Exec_Regs: Record Case Integer Of
1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: Integer);
2: (AL,AH,BL,BH,CL,CH,DL,DH: Byte);
End;
{ NOTE: the above variable is referenced in an Inline statement. It MUST
be a global variable (not a local variable or a typed constant)!! Ignore
this and you'll find yourself in Wonderland faster than you can reach
for the off switch}
Function GetEnvStr(SearchString: Exec_Str255): Exec_Str255;
Type
Env=Array [0..32767] Of Char;
Var
EPtr: ^Env;
EStr: Exec_Str255;
Done: Boolean;
I: Integer;
Begin
GetEnvStr:='';
If SearchString<>'' Then
Begin
EPtr:=Ptr(MemW[CSeg:$002C],0);
I:=0;
SearchString:=SearchString+'=';
Done:=False;
EStr:='';
Repeat
If EPtr^[I]=#0 Then
Begin
If EPtr^[Succ(I)]=#0 Then
Begin
Done:=True;
If SearchString='==' Then
Begin
EStr:='';
I:=I+4;
While EPtr^[I]<>#0 Do
Begin
EStr:=EStr+EPtr^[I];
I:=Succ(I);
End;
GetEnvStr:=EStr;
End;
End;
If Copy(EStr,1,Length(SearchString))=SearchString Then
Begin
GetEnvStr:=Copy(EStr,Succ(Length(SearchString)),255);
Done:=True;
End;
EStr:='';
End
Else EStr:=EStr+EPtr^[I];
I:=Succ(I);
Until Done;
End;
End;
Function ComSpec: Exec_Str66;
Begin
ComSpec:=GetEnvStr('COMSPEC');
End;
Function Exec(CommandLine: Exec_Str255): Integer;
Const
SSSave: Integer=0;
SPSave: Integer=0;
Var
FCB1,FCB2: Array [0..36] Of Byte; {*}
PathName: Exec_Str66; {*}
CommandTail: Exec_Str255;
ParmTable: Record {*}
EnvSeg: Integer;
ComLin: ^Integer;
FCB1Pr: ^Integer;
FCB2Pr: ^Integer;
End;
RegsFlags: Integer; {*}
{*: these variables are accessed in an Inline statement; their
declarations must not be changed }
Begin
(* Process the command, making sure that its in proper format *)
If Pos(' ',CommandLine)=0 Then
Begin
PathName:=CommandLine+#0;
CommandTail:=^M;
End
Else
Begin
PathName:=Copy(CommandLine,1,Pred(Pos(' ',CommandLine)))+#0;
CommandTail:=Copy(CommandLine,Pos(' ',CommandLine),255)+^M;
End;
CommandTail[0]:=Pred(CommandTail[0]);
(* Now set up the Function 4B data block *)
With Exec_Regs Do
Begin
FillChar(FCB1,Sizeof(FCB1),0);
AX:=$2901;
DS:=Seg(CommandTail[1]);
SI:=Ofs(CommandTail[1]);
ES:=Seg(FCB1);
DI:=Ofs(FCB1);
MsDos(Exec_Regs); { Create FCB 1 }
FillChar(FCB2,Sizeof(FCB2),0);
AX:=$2901;
ES:=Seg(FCB2);
DI:=Ofs(FCB2);
MsDos(Exec_Regs); { Create FCB 2 }
With ParmTable Do
Begin
EnvSeg:=MemW[CSeg:$002C]; { Makes sure valid environ is passed }
ComLin:=Addr(CommandTail);
FCB1Pr:=Addr(FCB1);
FCB2Pr:=Addr(FCB2);
End;
(* Now this inline does the actual work. It could be done without
inline code, but with so much stack manipulation I felt more
comfortable doing it in this manner. Not that no allocation of
memory is necessary since Turbo automatically does that. (Isn't
that nice of them!) *)
InLine($8D/$96/ PathName /$42/ { <DX>:=Ofs(PathName[1]); }
$8D/$9E/ ParmTable / { <BX>:=Ofs(ParmTable); }
$B8/$00/$4B/ { <AX>:=$4B00; }
$1E/$55/ { Save <DS>, <BP> }
$16/$1F/ { <DS>:=Seg(PathName[1]); }
$16/$07/ { <ES>:=Seg(ParmTable); }
$2E/$8C/$16/ SSSave / { Save <SS> in SSSave }
$2E/$89/$26/ SPSave / { Save <SP> in SPSave }
$FA/ { Disable interrupts }
$CD/$21/ { Call PC-DOS }
$FA/ { Disable interrupts }
$2E/$8B/$26/ SPSave / { Restore <SP> }
$2E/$8E/$16/ SSSave / { Restore <SS> }
$FB/ { Enable interrupts }
$5D/$1F/ { Restore <BP>,<DS> }
$9C/$8F/$86/ RegsFlags / { Flags:=<CPU flags> }
$A3/ Exec_Regs ); { Exec_Regs.AX:=<AX>; }
If (RegsFlags And 1)<>0 Then Exec:=AX
Else Exec:=0;
End;
End;
Function ExecCommand(CommandLine: Exec_Str255): Integer;
Begin
ExecCommand := Exec(ComSpec +' /C '+CommandLine);
End;
Function Shell: Integer;
Begin
Shell:=Exec(ComSpec);
End;